/*********************************************************************************
 *      Copyright:  (C) 2022 Zhang xiangyun<1327295677@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  client.c
 * 0  Description:  This file is client code for get temperature
 *                 
 *        Version:  1.0.0(16/04/22)
 *         Author:  Zhang xiangyun <1327295677@qq.com>
 *      ChangeLog:  1, Release initial version on "16/04/22 21:41:38"
 *                 
 ********************************************************************************/


#if 1

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <getopt.h>
#include <libgen.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sqlite3.h>
#include <time.h>


#include "ds18b20.h"  /* function:get_temperature() */
#include "client.h"   /* function:client_socket_init(),client_socket_senddata() */
#include "database.h" /* function:about sqlite3 database */
#include "logger.h"   /* function:logger system */
#include "setsig.h"
#include "pack.h"



static inline void print_usage(char*progname);
int check_sample_time(time_t *last_time,int interval);

#endif


int main(int argc,char **argv)
{
#if  1
	int                       opt=-1;
	int                       interval=30;
	int                       daemon_run=0;
	int                       server_port=0;
	int                       connect_rv=-1;
	int                       socket_fd=-1;
	int                       rv=-1;
	int                       sock_failure=0;
	int                       sqlite_rv=-1;
	float                     temp=0;
	char                     *server_ip=NULL;                     
	char                     *progname=NULL;
	int                       table_exist=0;

	//char                     *data[3];
	//char                     *package[3];
	//char                      name_buf[64];
	//char                      temp_buf[64];
	//char                      time_buf[64];
	int                       sn=0;
	//struct tm*                current_tm;
	time_t                    last_time=0;
	char                      pack_buf[1024];
	pack_info_t               pack_info;
	int                       sample_flag=0;
	int                       pack_bytes;

	char                     *log_file="stdout";


#endif  
# if 1
	struct option             long_options[]=
	{
		{"deamon",no_argument,NULL,'b'},
		{"port",required_argument,NULL,'p'},
		{"ip",required_argument,NULL,'i'},
		{"time",required_argument,NULL,'t'},
		{"name",required_argument,NULL,'n'},
		{"help",no_argument,NULL,'h'},
		{NULL,0,NULL,0}
	};

	progname=basename(argv[0]);/* get program name */

	while((opt=getopt_long(argc,argv,"p:i:t:n:bh",long_options,NULL))!=-1)
	{
		switch(opt)
		{
			case 'p':
				server_port=atoi(optarg);
				break;
			case 'i':
				server_ip=optarg;
				break;
			case 't':
				interval=atoi(optarg);/* get sampling interval */
				break;
			case 'n':
				sn=atoi(optarg);
				break;
			case 'b':
				daemon_run=1;
				log_file="client.log";
				break;
			case 'h':  /* get help information */
				print_usage(progname);
				return EXIT_SUCCESS;
			default:
				break;
		}
	}


	if(!server_port || NULL==server_ip)
	{
		print_usage(progname);
		return -1;
	}


	/* install signal */
	if((install_signal())<0)
	{
		printf("install signal failure!\n");
		return -1;
	}

	

	if(daemon_run)
	{
		daemon(0,0);
	}

	if(logger_init(log_file,LOG_LEVEL_DEBUG)<0)
	{
		fprintf(stderr,"initial logger system failure\n");
		return -1;
	}



	log_info("\n-----------CLIENT START!------------\n");


	connect_rv=client_socket_connect(server_ip,server_port,&socket_fd);
	if(connect_rv<0)
	{
		log_error("connect socket server failure:%s\n",strerror(errno));
		sock_failure=1;
	}

	/* initial database */
	/*  sqlite_rv=sqlite3_open("temperature.db",&db);
	if(sqlite_rv<0)
	{
		log_error("open database failure:%s\n",sqlite3_errmsg(db));
		goto CleanUp;
	}
	*/
	sqlite_rv=sqlite_create_database();
	if(sqlite_rv<0)
	{
		goto CleanUp;
    }
	


	while(!g_stop)
	{
		sample_flag=0;
		if(check_sample_time(&last_time,interval))
		{
			log_debug("start sample temperature\n");
			if(get_temperature(&temp)<0)
			{
				log_error("sample temperature failure!\n");
				continue;
			}
			memset(pack_info.temper,0,sizeof(pack_info.temper));
			sprintf(pack_info.temper,"%.2f",temp);
			
			get_id(pack_info.serial_id,DEVID_LEN,sn);
			log_debug("pack_info.serial_id:%s\n",pack_info.serial_id);
			get_time(pack_info.sample_time);
			log_debug("pack_info.sample_time:%s\n",pack_info.sample_time);

			log_info("info:%s/%s/%s\n",pack_info.serial_id,pack_info.sample_time,pack_info.temper);

			pack_bytes=packet_data(pack_info,pack_buf,sizeof(pack_buf));

			sample_flag=1;
			
		}


		/* get time */

		if((socketconnected(socket_fd))==0)
		{
			sock_failure=1;
		}
		else
			sock_failure=0;


		if(sock_failure==1)
		{
			/* send data into database */
			if(sample_flag==1)
			{
				sqlite_data_insert(pack_info);
			}

			/* reconnect socket */
			log_warn("start to reconnect socket\n");
			connect_rv=client_socket_connect(server_ip,server_port,&socket_fd);
			if(connect_rv<0)
			{
				log_error("reconnect failure!\n");
			}
			else
			{
			    log_warn("reconnect socket success!\n");
				sock_failure=0;
			}
		}

		if(sock_failure==0)
		{
			if(sample_flag==1)
			{
				rv=socket_senddata(socket_fd,pack_buf,pack_bytes);
				if(rv<0)
				{
					close(socket_fd);
					sock_failure=1;
					log_error("connect failure!\n");
				}
				else
				{
					sock_failure=0;
				}
			}

			if((empty_table_determine())>0)
			{
				sqlite_select_firstdata(&pack_info);
				//log_info("select first data from database\n");
				log_info("serial_id:%s\n",pack_info.serial_id);
				log_info("sample_time:%s\n",pack_info.sample_time);
				log_info("temper:%s\n",pack_info.temper);

				pack_bytes=packet_data(pack_info,pack_buf,sizeof(pack_buf));

				if((socket_senddata(socket_fd,pack_buf,pack_bytes))<0)
				{
					sock_failure=1;
					close(socket_fd);
				}
				else
				{
					if((sqlite_data_delete())==0)
					{
						log_info("delete the first data of database!\n");
					}
				}
			}

		}

		log_debug("\n----------START SLEEP----------\n");

    	sleep(1);

	}

#endif

CleanUp:
	sqlite3_close(db);
	return 0;

}


#if 1
static inline void print_usage(char*progname)
{
	printf("usage:%s [OPTION]...\n",progname);
	printf("%s is socket client program for get temperature,which used to send temperature information to socket server\n");
	printf("\nMandatory arguments to long options are mandatory for short options too:\n");
	printf(" -b[daemon ] set program running on background\n");
	printf(" -p[port ]   set socket server port address\n");
	printf(" -i[ip]      set socket server ip address\n");
	printf(" -t[time]    set sampling interval,default interval is 30 second\n ");
	printf(" -n[name]    set username\n");
	printf(" -h[help]    display this help information\n");
	printf("\nEXAMPLE:%s -b -p7300 -i192.168.0.185 -t50 -n1\n",progname);
	return;
}
#endif

int check_sample_time(time_t *last_time,int interval)
{
	int      need=0;
	time_t   now;

	time(&now);
	if(now >= *last_time+interval)
	{
		need=1;
		*last_time=now;
	}
	return need;
}

